package cn.edu.dgut.css.sai.springdatajpademo;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;

import javax.persistence.*;
import javax.transaction.Transactional;
import java.io.Serializable;

@SpringBootApplication
public class SpringDataJpaDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringDataJpaDemoApplication.class, args);
    }

    @Bean
    CommandLineRunner initDataSource(UserService userService) {
        return args -> {
            userService.createNewAccount("Li Zhixiong", "123456", 888);
            userService.createNewAccount("老王", "123456", 1000);
            userService.createNewAccount("蒙犽", "123456", 888);
            userService.createNewAccount("后羿", "123456", 777);
            userService.createNewAccount("伽罗", "123456", 666);
            userService.createNewAccount("凯", "123456", 555);
        };
    }
}

@Entity
@Table(name = "t_accountinfo")
@Data
class AccountInfo implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long accountId;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "userinfo_id")
    private UserInfo userInfo;
    private Integer balance;
}

@Entity
@Table(name = "t_userinfo")
@Data
class UserInfo implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long userid;
    private String username;
    private String password;
}

/**
 * 持久层接口 UserDao
 *
 * 定义接口即可，持久层业务的实现由spring data jpa帮你完成。
 *
 * 你需要做的，仅仅是根据spring data jpa命名方法的规则新增行方法声明
 *
 * 如果继承的是{@link JpaRepository},可以省去save方法的声明，观察{@link JpaRepository}已有的方法声明。
 *
 * @see org.springframework.data.repository.Repository
 * @see JpaRepository
 * @see org.springframework.data.repository.CrudRepository
 * @see org.springframework.data.jpa.repository.support.SimpleJpaRepository
 */
interface UserDao extends JpaRepository<AccountInfo, Long> {
    AccountInfo findByUserInfo_Username(String username);
    AccountInfo findByAccountId(Long accountId);
}

/**
 *  业务层接口 UserService
 */
interface UserService {
    AccountInfo createNewAccount(String username, String password, Integer initBalance);
    AccountInfo findOne(String username);
}

/**
 * 业务层的实现类 UserServiceImpl
 */
@Service("userService")
class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    @Transactional
    public AccountInfo createNewAccount(String username, String password, Integer initBalance){
        // 封装域对象
        AccountInfo accountInfo = new AccountInfo();
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(username);
        userInfo.setPassword(password);
        accountInfo.setBalance(initBalance);
        accountInfo.setUserInfo(userInfo);
        // 调用持久层，完成数据的保存
        return userDao.save(accountInfo);
    }

    @Override
    @Transactional
    public AccountInfo findOne(String username) {
        return userDao.findByUserInfo_Username(username);
    }
}
